package com.czy.facecompare.service.impl;

import com.baidu.idl.main.facesdk.FaceAuth;
import com.baidu.idl.main.facesdk.FaceDetect;
import com.baidu.idl.main.facesdk.FaceFeature;
import com.baidu.idl.main.facesdk.callback.Callback;
import com.baidu.idl.main.facesdk.model.BDFaceImageInstance;
import com.baidu.idl.main.facesdk.model.BDFaceInstance;
import com.baidu.idl.main.facesdk.model.BDFaceSDKCommon.FeatureType;
import com.baidu.idl.main.facesdk.model.BDFaceSDKCommon.BDFaceImageType;
import com.baidu.idl.main.facesdk.model.BDFaceSDKCommon.FaceQualityType;
import com.czy.facecompare.ResultState;
import com.czy.facecompare.service.BaiduAi;
import org.springframework.stereotype.Service;

/**
 *  百度AI封装接口
 *  //https://gitee.com/xshuai/BaiDuFaceOfflineSample
 * //https://ai.baidu.com/ai-doc/FACE/pk37c1mqu#%E6%AD%A5%E9%AA%A4%E4%B8%80%EF%BC%9Ainitmodel%EF%BC%88%EF%BC%89%E5%88%9D%E5%A7%8B%E5%8C%96%E6%A8%A1%E5%9E%8B%E8%83%BD%E5%8A%9B-br
 */

@Service
public class BaiduAiImpl implements BaiduAi {

    // 创建鉴权对象
    private FaceAuth faceAuth = new FaceAuth();

    // 人脸实例对象
    private BDFaceInstance bdFaceInstance;

    // 人脸探测器
    private FaceDetect faceDetect;

    // 人脸特征提取器
    private FaceFeature faceFeature;

    // 构造参数实例化成员变量
    public BaiduAiImpl() {
        // 创建FaceInstance 实例对象
        this.bdFaceInstance = new BDFaceInstance();
        this.bdFaceInstance.creatInstance();
        // 创建人脸探测器
        this.faceDetect = new FaceDetect(this.bdFaceInstance);
        // 创建人脸提取器
        this.faceFeature = new FaceFeature(this.bdFaceInstance);
    }

    /**
     *  离线注册
     * @param context   上下文对象
     * @return
     */
    @Override
    public void initOffLine(Context context) {

        // 离线激活
        faceAuth.initLicenseOffLine(context, new Callback() {
            @Override
            public void onResponse(int code, String s) {

                ResultState resultState = stateCheck(code);
                if (resultState.getCode() != 0){
                    System.out.println("离线激活失败");
                    return;
                }
                return;
            }
        });
        return;
    }

    /**
     * 新版本模型加载
     * @param context
     * @param idPhotoModel
     * @param visModel
     * @param nirModel
     * @param rgbdModel
     * @param callback
     */
//    @Override
//    public void initModel(Context context, String idPhotoModel, String visModel, String nirModel, String rgbdModel, Callback callback) {
//
//    }

    /**
     *  图片的质量和遮挡检测
     * @param context   上下文对象
     * @return
     */
    @Override
    public void initQuality(Context context) {

        faceDetect.initQuality(context, FaceQualityType.BLUR, FaceQualityType.OCCLUSION, new Callback() {
            @Override
            public void onResponse(int code, String s) {

                ResultState resultState = stateCheck(code);
                if (resultState.getCode() != 0){

                    return;
                }
                return;
            }
        });
        return;
    }

    /**
     *  创建图片实例
     * @param data      图片byte数组数据
     * @param height    图片高度
     * @param width     图片宽度
     * @return
     */
    @Override
    public BDFaceImageInstance createImage(byte[] data, int height, int width) {

        int isMbyteArrayror = 0;
        float angle = 0;

        // 获得图片信息
//        imageInstance.getImage();
        // 销毁图片
//        imageInstance.destory();
        // 创建图片对象
        return new BDFaceImageInstance(data,height,width, BDFaceImageType.BDFACE_IMAGE_TYPE_RGB,angle,isMbyteArrayror);
    }

    /**
     *  ⽆RGBD特征提取
     * @param imageInstance 图片实例
     * @param landmarks     检测后产出的数据 512
     * @param feature       特征的存储  512
     * @return
     */
    @Override
    public float getFeature(BDFaceImageInstance imageInstance, float[] landmarks, byte[] feature) {
                                                        //证件照                                       //true返回1-100 false返回 0-1
        float feature1 = faceFeature.feature(FeatureType.BDFACE_FEATURE_TYPE_ID_PHOTO, imageInstance, landmarks, feature);

        return feature1;
    }

    /**
     *  有RGBD特征提取
     * @param imageInstance
     * @param imageInstance_depth
     * @param landmarks
     * @param feature
     * @return
     */
    @Override
    public float getFeatureRGBD(BDFaceImageInstance imageInstance, BDFaceImageInstance imageInstance_depth, float[] landmarks, byte[] feature) {

        float feature1 = faceFeature.featureRGBD(FeatureType.BDFACE_FEATURE_TYPE_ID_PHOTO,imageInstance,imageInstance_depth,landmarks,feature);

        return feature1;
    }

    @Override
    public float featureCompare(byte[] feature1, byte[] feature2, boolean isPercent) {
                                                    //证件照              //特征1 //特征2   //true返回1-100 false返回 0-1
        float v = faceFeature.featureCompare(FeatureType.BDFACE_FEATURE_TYPE_ID_PHOTO, feature1, feature2, isPercent);
        return 0;
    }


    /**
     * 模型卸载
     */
    @Override
    public void uninitModel() {
        faceFeature.uninitModel();
    }

    /**
     *  对返回的结果状态码进行判断啊
     * @param code  结果状态码
     * @return
     */
    @Override
    public ResultState stateCheck(int code) {

        ResultState resultState = new ResultState();
        resultState.setCode(code);
        switch (code){
            case 0:
                resultState.setMessage("成功");
                break;
            case 1:
                resultState.setMessage("context 为null或者模型路径错");
                break;
            case -1:
                resultState.setMessage("⾮法的参数");
                break;
            case -2:
                resultState.setMessage("⾮法的参数");
                break;
            case -3:
                resultState.setMessage("⾮法的参数");
                break;
            case -4:
                resultState.setMessage("模型内容为空");
                break;
            case -5:
                resultState.setMessage("不⽀持的能⼒类型");
                break;
            case -6:
                resultState.setMessage("不⽀持预测类型");
                break;
            case -7:
                resultState.setMessage("预测库对象创建失败");
                break;
            case -8:
                resultState.setMessage("预测库初始化失败");
                break;
            case -9:
                resultState.setMessage("图像数据为空");
                break;
            case -10:
                resultState.setMessage("⼈脸能⼒初始化失败");
                break;
            case -11:
                resultState.setMessage("能⼒未加载");
                break;
            case -12:
                resultState.setMessage("⼈脸能⼒已加载");
                break;
            case -13:
                resultState.setMessage("未授权");
                break;
            case -14:
                resultState.setMessage("⼈脸能⼒运⾏异常");
                break;
            case -15:
                resultState.setMessage("不⽀持的图像类型");
                break;
            case -16:
                resultState.setMessage("图像转换失败");
                break;
        }
        return resultState;
    }
}

// 1:N特征设置
//说明：特征集合预加载接⼝，继承Feature，必须初始化id 和 feature 字段，⽤于1：N 内部实现和数据返回。
//public int featurePush(List<? extends Feature> features)


// 1:N特征⽐对
//说明：当前feature和预加载Feature 集合⽐对，返回预加载Feature集合中命中的id，feature 字段和⽐对分值score；⽤户可以通过id 在数据库中查找全量信息。
//ArrayList<Feature> featureSearch(byte[] firstFaceFeature, FeatureType featureType,int topNum, boolean isPercent)

// 卸载特征模型
//void uninitModel()


/**
 *
 *
 * //    File picture = new File("E:/PrintScreen/StarSky.jpg");
 * //12         BufferedImage sourceImg = ImageIO.read(new FileInputStream(picture));
 * //13
 * //14         System.out.println(String.format("Size: %.1f KB", picture.length()/1024.0));
 * //15         System.out.println("Width: " + sourceImg.getWidth());
 * //16         System.out.println("Height: " + sourceImg.getHeight());
 */